package com.th3t.enhance.akka.tutorial;

import akka.actor.ActorRef;
import akka.actor.ActorSystem;
import akka.actor.Props;

import com.th3t.enhance.akka.tutorial.actor.Listener;
import com.th3t.enhance.akka.tutorial.actor.Master;
import com.th3t.enhance.akka.tutorial.msg.CalculateMsg;

public class Pi {

	public static void main(String[] args) {
		Pi pi = new Pi();
		pi.calculate(5, 1000, 10000);
//		Pi approximation: 		3.1415925535897866
//		Calculation time: 	111 milliseconds
		
//		pi.calculate(5, 10000, 10000);
//		Pi approximation: 		3.1415926435897883
//		Calculation time: 	448 milliseconds
		
//		pi.calculate(5, 10000, 100000);
//		Pi approximation: 		3.141592652589859
//		Calculation time: 	4107 milliseconds

//		pi.calculate(10, 10000, 100000);
//		Pi approximation: 		3.1415926525898588
//		Calculation time: 	4058 milliseconds
		
//		pi.calculate(20, 10000, 100000);
//		Pi approximation: 		3.141592652589859
//		Calculation time: 	4081 milliseconds
		
	}

	/**
	 * pi的计算方法
	 * 0-无穷累计((-1)^n/(2n+1))=1-1/3+1/5-1/7+...=pi/4
	 * @param nrOfWorkers	工作者(角色)--合适的大小，多则实例化以及维护成本高，少则计算性能有限
	 * @param nrOfElements	一次性参与计算的分数，如一次计算m个 (-1)^n/(2n+1)
	 * @param nrOfMessages 消息数量，此参数决定了要计算多少次，即nm*m值越大越精确
	 */
	public void calculate(final int nrOfWorkers, final int nrOfElements,
			final int nrOfMessages) {
		// Create an Akka system
		ActorSystem system = ActorSystem.create("PiSystem");

		// create the result listener, which will print the result and shutdown the system
		final ActorRef listener = system.actorOf(Props.create(Listener.class),"listener");

		// create the master
		ActorRef master = system.actorOf(Master.props(nrOfWorkers, nrOfMessages, nrOfElements, listener),"master");

		// start the calculation
		master.tell(new CalculateMsg(), ActorRef.noSender());

	}
}
